package com.fare.taluo.queue.template;

import java.util.ArrayList;
import java.util.List;

import org.apache.log4j.Logger;

import com.fare.taluo.vo.queue.QueueBaseVO;
import com.fare.taluo.application.queue.IScheduleQueueApplication;
import com.foreveross.threadpool.queue.WorkQueue;
import com.foreveross.threadpool.queue.impl.AbstractWorkQueue;
import com.foreveross.threadpool.util.ExceptionUtils;
/**
 * 队列池计划任务模板
 * @author creator: xiangsf
 * @author modifior: xiangsf
 * @since 2012-12-19 下午1:51:22
 * @version v1.0
 */
public abstract class ScheduleQueueTemplate<T extends WorkQueue, X extends QueueBaseVO> extends AbstractWorkQueue {
	
	protected Logger logger = Logger.getLogger(getClass());

	public ScheduleQueueTemplate(){}
	
	public abstract IScheduleQueueApplication<X> getApplication();
	/**
	 * 将代理对象包装成任务对象
	 * <p>若从仓库中获取的本身就是任务队列对象，则不需要进行代理包装
	 * @param vo
	 * @return
	 */
	public abstract T delegate(X vo);
	/**
	 * 获得代理的源
	 * @return
	 */
	public abstract X getDelegateSource();

	@Override
	public List<WorkQueue> getWorkTaskBatch(int num) {
		List<WorkQueue> queues = new ArrayList<WorkQueue>();
		List<X> list = null;
		long st = System.currentTimeMillis();
		try {
			list = getApplication().getPlanTask(num);
			if(list != null){
				for(X vo : list){
					queues.add(delegate(vo));
				}
			}
		} catch (Exception e) {
			logger.error("无法获取计划内任务队列！", e);
		}finally{
			list = null;
		}
		if(logger.isDebugEnabled()){
			logger.debug("获取计划内任务，耗时："+(System.currentTimeMillis()-st));
		}
		return queues;
	}

	@Override
	public void execute() throws Exception {
		X vo = this.getDelegateSource();
		if(vo != null){
			long st = System.currentTimeMillis();
			if(logger.isDebugEnabled()){
				logger.debug("开始执行任务："+vo.getName());
			}
			
			try{
				//更新状态为正在执行，实际开始时间为当前时间
				if(getApplication().load(vo.getId())){
					//真正执行任务（业务）
					getApplication().execute(vo.getId());
					vo.setStatus(WorkQueue.STATUS_COMPLETE);
				}else{
					vo.setStatus(WorkQueue.STATUS_FAIL);
					vo.setRecLog("任务已丢弃!");
				}
			}catch(Exception e){
				//出现异常，记录异常信息
				vo.setStatus(WorkQueue.STATUS_FAIL);
				String exestr = ExceptionUtils.exceptionToString(e);
				vo.setRecLog(exestr.length() > 2000 ? exestr.substring(0, 2000) : exestr);
			}finally{
				//归档
				getApplication().archive(vo);
				//创建下一周期任务
				getApplication().createNext(vo.getId());
				if(logger.isDebugEnabled()){
					logger.debug("执行任务："+vo.getName()+"，结束，耗时："+(System.currentTimeMillis()-st));
				}
				vo = null;
			}
		}
	}

}
